<!doctype html>
<html lang="en-US">
  <head>
    <link href="/assets/index.css" rel="stylesheet" type="text/css" />
    <style type="text/css">
      /* TODO: [P*] Can we eliminate this style? */
      .fui-FluentProvider,
      .webchat-fluent {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <main id="webchat"></main>
    <!-- Redirect packages on esm.sh loaded by `@fluentui/react-components` -->
    <script type="importmap">
      {
        "imports": {
          "@fluentui/react-components": "https://esm.sh/@fluentui/react-components?deps=react@18.3.1,react-dom@18.3.1&exports=FluentProvider,createDarkTheme,webLightTheme",
          "botframework-webchat": "/__dist__/packages/bundle/static/botframework-webchat.js",
          "botframework-webchat/component": "/__dist__/packages/bundle/static/botframework-webchat/component.js",
          "botframework-webchat/decorator": "/__dist__/packages/bundle/static/botframework-webchat/decorator.js",
          "botframework-webchat/hook": "/__dist__/packages/bundle/static/botframework-webchat/hook.js",
          "botframework-webchat/internal": "/__dist__/packages/bundle/static/botframework-webchat/internal.js",
          "botframework-webchat-fluent-theme": "/__dist__/packages/fluent-theme/static/botframework-webchat-fluent-theme.js",
          "jest-mock": "https://esm.sh/jest-mock",
          "react": "/__dist__/packages/bundle/static/react.js",
          "react-dom": "/__dist__/packages/bundle/static/react-dom.js",
          "react-dom/client": "/__dist__/packages/bundle/static/react-dom/client.js",
          "https://esm.sh/react@18.3.1/es2022/react.mjs": "/__dist__/packages/bundle/static/react.js",
          "https://esm.sh/react@18.3.1/es2022/react-dom.mjs": "/__dist__/packages/bundle/static/react-dom.18.js",
          "https://esm.sh/react@18.3.1/es2022/react-dom/client.mjs": "/__dist__/packages/bundle/static/react-dom.18/client.js"
        }
      }
    </script>
    <script type="module">
      import '/test-harness.mjs';
      import '/test-page-object.mjs';

      import { FluentProvider, webLightTheme } from '@fluentui/react-components';
      import { createDirectLine, createStoreWithOptions, hooks, ReactWebChat } from 'botframework-webchat';
      import { ThemeProvider } from 'botframework-webchat/component';
      import { InjectStyleElements } from 'botframework-webchat/internal';
      import { FluentThemeProvider } from 'botframework-webchat-fluent-theme';
      import { spyOn } from 'jest-mock';
      import { createElement, Fragment } from 'react';
      import { flushSync } from 'react-dom';
      import { createRoot } from 'react-dom/client';

      const consoleError = console.error.bind(console);

      spyOn(console, 'error').mockImplementation((...args) => {
        const [message] = args;

        if (
          typeof message !== 'string' ||
          !(
            message.includes(
              'Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.'
            ) ||
            message.includes('ReactDOM.render is no longer supported in React 18. Use createRoot instead.') ||
            // TODO: [P0] We should fix the "Cannot update a component while rendering a different component" error.
            (message.includes('Cannot update a component') && message.includes('while rendering a different component'))
          )
        ) {
          consoleError(...args);
        }
      });

      const { useStyleOptions } = hooks;
      const {
        testHelpers: { createDirectLineEmulator }
      } = window;

      // TODO: This is for `createDirectLineEmulator` only, should find ways to eliminate this line.
      window.WebChat = { createStoreWithOptions };

      run(async function () {
        const { directLine, store } = createDirectLineEmulator();

        const fluentTheme = {
          ...webLightTheme,
          // Original is #242424 which is too light for fui-FluentProvider to pass our accessibility checks.
          colorNeutralForeground1: '#1b1b1b'
        };

        const styleElement = document.createElement('style');

        // TODO: [P0] Is the CSS selector a good story for overriding CSS?
        styleElement.textContent = `.webchat-with-overrides { --webchat__font--primary: 'Courier New', monospace; }`;

        const root = createRoot(document.getElementsByTagName('main')[0]);

        function render(stylesRoot) {
          flushSync(() =>
            root.render(
              createElement(
                Fragment,
                {},
                createElement(InjectStyleElements, {
                  at: stylesRoot,
                  nonce: undefined,
                  styleElements: [styleElement]
                }),
                createElement(
                  FluentProvider,
                  { className: 'fui-FluentProvider', theme: fluentTheme },
                  createElement(
                    FluentThemeProvider,
                    {
                      stylesRoot,
                      variant: 'fluent'
                    },
                    createElement(
                      ReactWebChat,
                      {
                        className: 'webchat-with-overrides',
                        directLine,
                        store
                      }
                    )
                  )
                )
              )
            )
          );
        }

        render();

        await pageConditions.uiConnected();

        const styleElements = document.head.querySelectorAll('[data-webchat-injected]');

        // THEN: Should have 5 <style> elements.
        expect(styleElements).toHaveLength(5);

        // THEN: <style> should be strictly ordered as below.
        expect(Array.from(styleElements).map(element => element.dataset['webchatInjected'])).toEqual([
          '',
          'fluent-theme',
          'component/decorator',
          'component',
          expect.stringMatching(/^component\/CustomPropertiesContainer-/)
        ]);

        await directLine.emulateIncomingActivity('Hello, World!');

        await pageConditions.numActivitiesShown(1);

        // THEN: Should show the message using "Courier New" or monospace font.
        await host.snapshot('local');

        // WHEN: Move `stylesRoot` to document.body.
        render(document.body);

        // THEN: Should remove all 5 style elements from document.head.
        expect(document.head.querySelectorAll('[data-webchat-injected]')).toHaveLength(0);

        // THEN: Should move all 5 style elements to document.body.
        const styleElementsInBody = document.body.querySelectorAll('[data-webchat-injected]');

        expect(styleElementsInBody).toHaveLength(5);

        // THEN: <style> should be strictly ordered as below.
        expect(Array.from(styleElementsInBody).map(element => element.dataset['webchatInjected'])).toEqual([
          '',
          'fluent-theme',
          'component/decorator',
          'component',
          expect.stringMatching(/^component\/CustomPropertiesContainer-/)
        ]);
      });
    </script>
  </body>
</html>
